home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0992.ARJ / WINDOW.C < prev    next >
Text File  |  1992-06-29  |  15KB  |  505 lines

  1. /* ---------- window.c ------------- */
  2.  
  3. #include "dflat.h"
  4.  
  5. WINDOW inFocus = NULL;
  6.  
  7. int foreground, background;   /* current video colors */
  8.  
  9. static void TopLine(WINDOW, int, RECT);
  10.  
  11. /* --------- create a window ------------ */
  12. WINDOW CreateWindow(
  13.     CLASS class,              /* class of this window       */
  14.     char *ttl,                /* title or NULL              */
  15.     int left, int top,        /* upper left coordinates     */
  16.     int height, int width,    /* dimensions                 */
  17.     void *extension,          /* pointer to additional data */
  18.     WINDOW parent,            /* parent of this window      */
  19.     int (*wndproc)(struct window *,enum messages,PARAM,PARAM),
  20.     int attrib)               /* window attribute           */
  21. {
  22.     WINDOW wnd = DFcalloc(1, sizeof(struct window));
  23.     get_videomode();
  24.     if (wnd != NULL)    {
  25.         int base;
  26.         /* ----- height, width = -1: fill the screen ------- */
  27.         if (height == -1)
  28.             height = SCREENHEIGHT;
  29.         if (width == -1)
  30.             width = SCREENWIDTH;
  31.         /* ----- coordinates -1, -1 = center the window ---- */
  32.         if (left == -1)
  33.             wnd->rc.lf = (SCREENWIDTH-width)/2;
  34.         else
  35.             wnd->rc.lf = left;
  36.         if (top == -1)
  37.             wnd->rc.tp = (SCREENHEIGHT-height)/2;
  38.         else
  39.             wnd->rc.tp = top;
  40.         wnd->attrib = attrib;
  41.         if (ttl != NULL)
  42.             AddAttribute(wnd, HASTITLEBAR);
  43.         if (wndproc == NULL)
  44.             wnd->wndproc = classdefs[class].wndproc;
  45.         else
  46.             wnd->wndproc = wndproc;
  47.         /* ---- derive attributes of base classes ---- */
  48.         base = class;
  49.         while (base != -1)    {
  50.             AddAttribute(wnd, classdefs[base].attrib);
  51.             base = classdefs[base].base;
  52.         }
  53.         if (parent)    {
  54.             if (!TestAttribute(wnd, NOCLIP))    {
  55.                 /* -- keep upper left within borders of parent - */
  56.                 wnd->rc.lf = max(wnd->rc.lf,GetClientLeft(parent));
  57.                 wnd->rc.tp = max(wnd->rc.tp,GetClientTop(parent));
  58.             }
  59.         }
  60.         else
  61.             parent = ApplicationWindow;
  62.         wnd->class = class;
  63.         wnd->extension = extension;
  64.         wnd->rc.rt = GetLeft(wnd)+width-1;
  65.         wnd->rc.bt = GetTop(wnd)+height-1;
  66.         wnd->ht = height;
  67.         wnd->wd = width;
  68.         if (ttl != NULL)
  69.             InsertTitle(wnd, ttl);
  70.         wnd->parent = parent;
  71.         wnd->oldcondition = wnd->condition = ISRESTORED;
  72.         wnd->RestoredRC = wnd->rc;
  73.         InitWindowColors(wnd);
  74.         SendMessage(wnd, CREATE_WINDOW, 0, 0);
  75.         if (isVisible(wnd))
  76.             SendMessage(wnd, SHOW_WINDOW, 0, 0);
  77.     }
  78.     return wnd;
  79. }
  80.  
  81. /* -------- add a title to a window --------- */
  82. void AddTitle(WINDOW wnd, char *ttl)
  83. {
  84.     InsertTitle(wnd, ttl);
  85.     SendMessage(wnd, BORDER, 0, 0);
  86. }
  87.  
  88. /* ----- insert a title into a window ---------- */
  89. void InsertTitle(WINDOW wnd, char *ttl)
  90. {
  91.     wnd->title=DFrealloc(wnd->title,strlen(ttl)+1);
  92.     strcpy(wnd->title, ttl);
  93. }
  94.  
  95. static unsigned char line[300];
  96.  
  97. /* ------ write a line to video window client area ------ */
  98. void writeline(WINDOW wnd, char *str, int x, int y, BOOL pad)
  99. {
  100.     char *cp;
  101.     int len;
  102.     int dif;
  103.     char wline[200];
  104.  
  105.     memset(wline, 0, 200);
  106.     len = LineLength(str);
  107.     dif = strlen(str) - len;
  108.     strncpy(wline, str, ClientWidth(wnd) + dif);
  109.     if (pad)    {
  110.         cp = wline+strlen(wline);
  111.         while (len++ < ClientWidth(wnd)-x)
  112.             *cp++ = ' ';
  113.     }
  114.     wputs(wnd, wline, x, y);
  115. }
  116.  
  117. RECT AdjustRectangle(WINDOW wnd, RECT rc)
  118. {
  119.     /* -------- adjust the rectangle ------- */
  120.     if (TestAttribute(wnd, HASBORDER))    {
  121.         if (RectLeft(rc) == 0)
  122.             --rc.rt;
  123.         else if (RectLeft(rc) < RectRight(rc) &&
  124.                 RectLeft(rc) < WindowWidth(wnd)+1)
  125.             --rc.lf;
  126.     }
  127.     if (TestAttribute(wnd, HASBORDER | HASTITLEBAR))    {
  128.         if (RectTop(rc) == 0)
  129.             --rc.bt;
  130.         else if (RectTop(rc) < RectBottom(rc) &&
  131.                 RectTop(rc) < WindowHeight(wnd)+1)
  132.             --rc.tp;
  133.     }
  134.     RectRight(rc) = max(RectLeft(rc),
  135.                         min(RectRight(rc),WindowWidth(wnd)));
  136.     RectBottom(rc) = max(RectTop(rc),
  137.                         min(RectBottom(rc),WindowHeight(wnd)));
  138.     return rc;
  139. }
  140.  
  141. /* -------- display a window's title --------- */
  142. void DisplayTitle(WINDOW wnd, RECT *rcc)
  143. {
  144.     if (GetTitle(wnd) != NULL)    {
  145.         int tlen = min(strlen(GetTitle(wnd)), WindowWidth(wnd)-2);
  146.         int tend = WindowWidth(wnd)-3-BorderAdj(wnd);
  147.         RECT rc;
  148.  
  149.         if (rcc == NULL)
  150.             rc = RelativeWindowRect(wnd, WindowRect(wnd));
  151.         else
  152.             rc = *rcc;
  153.         rc = AdjustRectangle(wnd, rc);
  154.  
  155.         if (SendMessage(wnd, TITLE, (PARAM) rcc, 0))    {
  156.             if (wnd == inFocus)    {
  157.                 foreground = cfg.clr[TITLEBAR] [HILITE_COLOR] [FG];
  158.                 background = cfg.clr[TITLEBAR] [HILITE_COLOR] [BG];
  159.             }
  160.             else    {
  161.                 foreground = cfg.clr[TITLEBAR] [STD_COLOR] [FG];
  162.                 background = cfg.clr[TITLEBAR] [STD_COLOR] [BG];
  163.             }
  164.             memset(line,' ',WindowWidth(wnd));
  165. #ifdef INCLUDE_MINIMIZE
  166.             if (wnd->condition != ISMINIMIZED)
  167. #endif
  168.                 strncpy(line + ((WindowWidth(wnd)-2 - tlen) / 2),
  169.                     wnd->title, tlen);
  170.             if (TestAttribute(wnd, CONTROLBOX))
  171.                 line[2-BorderAdj(wnd)] = CONTROLBOXCHAR;
  172.             if (TestAttribute(wnd, MINMAXBOX))    {
  173.                 switch (wnd->condition)    {
  174.                     case ISRESTORED:
  175. #ifdef INCLUDE_MAXIMIZE
  176.                         line[tend+1] = MAXPOINTER;
  177. #endif
  178. #ifdef INCLUDE_MINIMIZE
  179.                         line[tend]   = MINPOINTER;
  180. #endif
  181.                         break;
  182. #ifdef INCLUDE_MINIMIZE
  183.                     case ISMINIMIZED:
  184.                         line[tend+1] = MAXPOINTER;
  185.                         break;
  186. #endif
  187. #ifdef INCLUDE_MAXIMIZE
  188.                     case ISMAXIMIZED:
  189. #ifdef INCLUDE_MINIMIZE
  190.                         line[tend]   = MINPOINTER;
  191. #endif
  192. #ifdef INCLUDE_RESTORE
  193.                         line[tend+1] = RESTOREPOINTER;
  194. #endif
  195.                         break;
  196. #endif
  197.                     default:
  198.                         break;
  199.                 }
  200.             }
  201.             line[RectRight(rc)+1] = line[tend+3] = '\0';
  202.             if (wnd != inFocus)
  203.                 ClipString++;
  204.             writeline(wnd, line+RectLeft(rc),
  205.                            RectLeft(rc)+BorderAdj(wnd),
  206.                            0,
  207.                            FALSE);
  208.             ClipString = 0;
  209.         }
  210.     }
  211. }
  212.  
  213. /* --- display right border shadow character of a window --- */
  214. static void near shadow_char(WINDOW wnd, int y)
  215. {
  216.     int fg = foreground;
  217.     int bg = background;
  218.     int x = WindowWidth(wnd);
  219.     int c = videochar(GetLeft(wnd)+x, GetTop(wnd)+y);
  220.  
  221.     if (TestAttribute(wnd, SHADOW) == 0 || cfg.mono)
  222.         return;
  223.     foreground = DARKGRAY;
  224.     background = BLACK;
  225.     wputch(wnd, c, x, y);
  226.     foreground = fg;
  227.     background = bg;
  228. }
  229.  
  230. /* --- display the bottom border shadow line for a window -- */
  231. static void near shadowline(WINDOW wnd, RECT rc)
  232. {
  233.     int i;
  234.     int y = GetBottom(wnd)+1;
  235.     int fg = foreground;
  236.     int bg = background;
  237.  
  238.     if ((TestAttribute(wnd, SHADOW)) == 0 || cfg.mono)
  239.         return;
  240.     for (i = 0; i < WindowWidth(wnd)+1; i++)
  241.         line[i] = videochar(GetLeft(wnd)+i, y);
  242.     line[i] = '\0';
  243.     foreground = DARKGRAY;
  244.     background = BLACK;
  245.     line[RectRight(rc)+1] = '\0';
  246.     if (RectLeft(rc) == 0)
  247.         rc.lf++;
  248.     ClipString++;
  249.     wputs(wnd, line+RectLeft(rc), RectLeft(rc),
  250.         WindowHeight(wnd));
  251.     --ClipString;
  252.     foreground = fg;
  253.     background = bg;
  254. }
  255.  
  256. static RECT ParamRect(WINDOW wnd, RECT *rcc)
  257. {
  258.     RECT rc;
  259.     if (rcc == NULL)    {
  260.         rc = RelativeWindowRect(wnd, WindowRect(wnd));
  261.         if (TestAttribute(wnd, SHADOW))    {
  262.             rc.rt++;
  263.             rc.bt++;
  264.         }
  265.     }
  266.     else
  267.         rc = *rcc;
  268.     return rc;
  269. }
  270.  
  271. void PaintShadow(WINDOW wnd)
  272. {
  273.     int y;
  274.     RECT rc = ParamRect(wnd, NULL);
  275.     for (y = 1; y < WindowHeight(wnd); y++)
  276.         shadow_char(wnd, y);
  277.     shadowline(wnd, rc);
  278. }
  279.  
  280. /* ------- display a window's border ----- */
  281. void RepaintBorder(WINDOW wnd, RECT *rcc)
  282. {
  283.     int y;
  284.     unsigned int lin, side, ne, nw, se, sw;
  285.     RECT rc, clrc;
  286.  
  287.     if (!TestAttribute(wnd, HASBORDER))
  288.         return;
  289.     rc = ParamRect(wnd, rcc);
  290.     clrc = AdjustRectangle(wnd, rc);
  291.  
  292.     if (wnd == inFocus)    {
  293.         lin  = FOCUS_LINE;
  294.         side = FOCUS_SIDE;
  295.         ne   = FOCUS_NE;
  296.         nw   = FOCUS_NW;
  297.         se   = FOCUS_SE;
  298.         sw   = FOCUS_SW;
  299.     }
  300.     else    {
  301.         lin  = LINE;
  302.         side = SIDE;
  303.         ne   = NE;
  304.         nw   = NW;
  305.         se   = SE;
  306.         sw   = SW;
  307.     }
  308.     line[WindowWidth(wnd)] = '\0';
  309.     /* ---------- window title ------------ */
  310.     if (TestAttribute(wnd, HASTITLEBAR))
  311.         if (RectTop(rc) == 0)
  312.             if (RectLeft(rc) < WindowWidth(wnd)-BorderAdj(wnd))
  313.                 DisplayTitle(wnd, &rc);
  314.     foreground = FrameForeground(wnd);
  315.     background = FrameBackground(wnd);
  316.     /* -------- top frame corners --------- */
  317.     if (RectTop(rc) == 0)    {
  318.         if (RectLeft(rc) == 0)
  319.             wputch(wnd, nw, 0, 0);
  320.         if (RectLeft(rc) < WindowWidth(wnd))    {
  321.             if (RectRight(rc) >= WindowWidth(wnd)-1)
  322.                 wputch(wnd, ne, WindowWidth(wnd)-1, 0);
  323.             TopLine(wnd, lin, clrc);
  324.         }
  325.     }
  326.  
  327.     /* ----------- window body ------------ */
  328.     for (y = RectTop(rc); y <= RectBottom(rc); y++)    {
  329.         int ch;
  330.         if (y == 0 || y >= WindowHeight(wnd)-1)
  331.             continue;
  332.         if (RectLeft(rc) == 0)
  333.             wputch(wnd, side, 0, y);
  334.         if (RectLeft(rc) < WindowWidth(wnd) &&
  335.                 RectRight(rc) >= WindowWidth(wnd)-1)    {
  336.             if (TestAttribute(wnd, VSCROLLBAR))
  337.                 ch = (    y == 1 ? UPSCROLLBOX      :
  338.                           y == WindowHeight(wnd)-2  ?
  339.                                 DOWNSCROLLBOX       :
  340.                           y-1 == wnd->VScrollBox    ?
  341.                                 SCROLLBOXCHAR       :
  342.                           SCROLLBARCHAR );
  343.             else
  344.                 ch = side;
  345.             wputch(wnd, ch, WindowWidth(wnd)-1, y);
  346.         }
  347.         if (RectRight(rc) == WindowWidth(wnd))
  348.             shadow_char(wnd, y);
  349.     }
  350.  
  351.     if (RectTop(rc) <= WindowHeight(wnd)-1 &&
  352.             RectBottom(rc) >= WindowHeight(wnd)-1)    {
  353.         /* -------- bottom frame corners ---------- */
  354.         if (RectLeft(rc) == 0)
  355.             wputch(wnd, sw, 0, WindowHeight(wnd)-1);
  356.         if (RectLeft(rc) < WindowWidth(wnd) &&
  357.                 RectRight(rc) >= WindowWidth(wnd)-1)
  358.             wputch(wnd, se, WindowWidth(wnd)-1,
  359.                 WindowHeight(wnd)-1);
  360.  
  361.  
  362.         if (wnd->StatusBar == NULL)    {
  363.             /* ----------- bottom line ------------- */
  364.             memset(line,lin,WindowWidth(wnd)-1);
  365.             if (TestAttribute(wnd, HSCROLLBAR))    {
  366.                 line[0] = LEFTSCROLLBOX;
  367.                 line[WindowWidth(wnd)-3] = RIGHTSCROLLBOX;
  368.                 memset(line+1, SCROLLBARCHAR, WindowWidth(wnd)-4);
  369.                 line[wnd->HScrollBox] = SCROLLBOXCHAR;
  370.             }
  371.             line[WindowWidth(wnd)-2] = line[RectRight(rc)] = '\0';
  372.             if (RectLeft(rc) != RectRight(rc) ||
  373.                 (RectLeft(rc) && RectLeft(rc) < WindowWidth(wnd)-1))    {
  374.                 if (wnd != inFocus)
  375.                     ClipString++;
  376.                 writeline(wnd,
  377.                             line+(RectLeft(clrc)),
  378.                             RectLeft(clrc)+1,
  379.                             WindowHeight(wnd)-1,
  380.                             FALSE);
  381.                 ClipString = 0;
  382.             }
  383.         }
  384.         if (RectRight(rc) == WindowWidth(wnd))
  385.             shadow_char(wnd, WindowHeight(wnd)-1);
  386.     }
  387.     if (RectBottom(rc) == WindowHeight(wnd))
  388.         /* ---------- bottom shadow ------------- */
  389.         shadowline(wnd, rc);
  390. }
  391.  
  392. static void TopLine(WINDOW wnd, int lin, RECT rc)
  393. {
  394.     if (TestAttribute(wnd, HASMENUBAR))
  395.         return;
  396.     if (TestAttribute(wnd, HASTITLEBAR) && GetTitle(wnd))
  397.         return;
  398.     if (RectLeft(rc) == 0)    {
  399.         RectLeft(rc) += BorderAdj(wnd);
  400.         RectRight(rc) += BorderAdj(wnd);
  401.     }
  402.     if (RectRight(rc) < WindowWidth(wnd)-1)
  403.         RectRight(rc)++;
  404.  
  405.     if (RectLeft(rc) < RectRight(rc))    {
  406.         /* ----------- top line ------------- */
  407.         memset(line,lin,WindowWidth(wnd)-1);
  408.         if (TestAttribute(wnd, CONTROLBOX))    {
  409.             strncpy(line+1, "   ", 3);
  410.             *(line+2) = CONTROLBOXCHAR;
  411.         }
  412.         line[RectRight(rc)] = '\0';
  413.         writeline(wnd, line+RectLeft(rc),
  414.             RectLeft(rc), 0, FALSE);
  415.     }
  416. }
  417.  
  418. /* ------ clear the data space of a window -------- */
  419. void ClearWindow(WINDOW wnd, RECT *rcc, int clrchar)
  420. {
  421.     if (isVisible(wnd))    {
  422.         int y;
  423.         RECT rc;
  424.  
  425.         if (rcc == NULL)
  426.             rc = RelativeWindowRect(wnd, WindowRect(wnd));
  427.         else
  428.             rc = *rcc;
  429.  
  430.         if (RectLeft(rc) == 0)
  431.             RectLeft(rc) = BorderAdj(wnd);
  432.         if (RectRight(rc) > WindowWidth(wnd)-1)
  433.             RectRight(rc) = WindowWidth(wnd)-1;
  434.         SetStandardColor(wnd);
  435.         memset(line, clrchar, sizeof line);
  436.         line[RectRight(rc)+1] = '\0';
  437.         for (y = RectTop(rc); y <= RectBottom(rc); y++)    {
  438.             if (y < TopBorderAdj(wnd) ||
  439.                     y > ClientHeight(wnd)+
  440.                         (TestAttribute(wnd, HASMENUBAR) ? 1 : 0))
  441.                 continue;
  442.             writeline(wnd,
  443.                 line+(RectLeft(rc)),
  444.                 RectLeft(rc),
  445.                 y,
  446.                 FALSE);
  447.         }
  448.     }
  449. }
  450.  
  451. /* ------ compute the logical line length of a window ------ */
  452. int LineLength(char *ln)
  453. {
  454.     int len = strlen(ln);
  455.     char *cp = ln;
  456.     while ((cp = strchr(cp, CHANGECOLOR)) != NULL)    {
  457.         cp++;
  458.         len -= 3;
  459.     }
  460.     cp = ln;
  461.     while ((cp = strchr(cp, RESETCOLOR)) != NULL)    {
  462.         cp++;
  463.         --len;
  464.     }
  465.     return len;
  466. }
  467.  
  468. void InitWindowColors(WINDOW wnd)
  469. {
  470.     int fbg,col;
  471.     int cls = GetClass(wnd);
  472.     /* window classes without assigned colors inherit parent's colors */
  473.     if (cfg.clr[cls][0][0] == 0xff && GetParent(wnd) != NULL)
  474.         cls = GetClass(GetParent(wnd));
  475.     /* ---------- set the colors ---------- */
  476.     for (fbg = 0; fbg < 2; fbg++)
  477.         for (col = 0; col < 4; col++)
  478.             wnd->WindowColors[col][fbg] = cfg.clr[cls][col][fbg];
  479. }
  480.  
  481. void PutWindowChar(WINDOW wnd, int c, int x, int y)
  482. {
  483.     if (x < ClientWidth(wnd) && y < ClientHeight(wnd))
  484.         wputch(wnd, c, x+BorderAdj(wnd), y+TopBorderAdj(wnd));
  485. }
  486.  
  487. void PutWindowLine(WINDOW wnd, void *s, int x, int y)
  488. {
  489.     int saved = FALSE, sv;
  490.     if (x < ClientWidth(wnd) && y < ClientHeight(wnd))    {
  491.         char *en = (char *)s+ClientWidth(wnd)-x;
  492.         if (strlen(s)+x > ClientWidth(wnd))    {
  493.             sv = *en;
  494.             *en = '\0';
  495.             saved = TRUE;
  496.         }
  497.         ClipString++;
  498.         wputs(wnd, s, x+BorderAdj(wnd), y+TopBorderAdj(wnd));
  499.         --ClipString;
  500.         if (saved)
  501.             *en = sv;
  502.     }
  503. }
  504.  
  505.